home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / omega / ogen2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-06  |  12.0 KB  |  509 lines

  1. /* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
  2. /* ogen2.c */
  3. /* level generator functions */
  4.  
  5. #include "oglob.h"
  6.  
  7.  
  8.  
  9. /* For each level, there should be one stairway going up and one down. 
  10. fromlevel determines whether the player is placed on the up or the down
  11. staircase. The aux value is currently unused elsewhere, but is set 
  12. to the destination level. */
  13.  
  14. void make_stairs(fromlevel)
  15. int fromlevel;
  16. {
  17.   int i,j;
  18.   /* no stairway out of astral */
  19.   if (Current_Environment != E_ASTRAL) {
  20.     findspace(&i,&j,-1);
  21.     Level->site[i][j].locchar = UP;
  22.     Level->site[i][j].aux = Level->depth-1;
  23.     lset(i,j,STOPS);
  24.     if (fromlevel < Level->depth) { 
  25.       Player.x = i;
  26.       Player.y = j;
  27.     }
  28.   }
  29.   if (Level->depth < MaxDungeonLevels) {
  30.     findspace(&i,&j,-1);
  31.     Level->site[i][j].locchar = DOWN;
  32.     Level->site[i][j].aux = Level->depth+1;
  33.     lset(i,j,STOPS);
  34.     if (fromlevel > Level->depth) { 
  35.       Player.x = i;
  36.       Player.y = j;
  37.     }
  38.   }
  39. }
  40.  
  41.  
  42.  
  43.  
  44.  
  45. /* tactical map generating functions */
  46.  
  47.  
  48. void make_country_screen(terrain)
  49. char terrain;
  50. {
  51.   int i,j;
  52.   TempLevel = Level;
  53.   if (ok_to_free(TempLevel)) {
  54.     free((char *) TempLevel);
  55.     TempLevel = NULL;
  56.   }
  57.   Level = ((plv) malloc(sizeof(levtype)));
  58.   clear_level(Level);
  59.   Level->environment = E_TACTICAL_MAP;
  60.   Level->generated = TRUE;
  61.   switch(terrain) {
  62.   case FOREST: make_forest(); break;
  63.   case JUNGLE: make_jungle(); break;
  64.   case SWAMP: make_swamp(); break;
  65.   case RIVER: make_river(); break;
  66.   case MOUNTAINS: case PASS: make_mountains(); break;
  67.   case ROAD: make_road(); break;
  68.   default: make_plains(); break;
  69.   }
  70.   if (nighttime()) {
  71.     print3("Night's gloom shrouds your sight.");    
  72.     for(i=0;i<WIDTH;i++)
  73.       for(j=0;j<LENGTH;j++) {
  74.     Level->site[i][j].showchar = ' ';    
  75.     Level->site[i][j].lstatus = 0;
  76.       }
  77.   }
  78. }
  79.  
  80. void make_plains()
  81. {
  82.   int i,j;
  83.  
  84.   for(i=0;i<WIDTH;i++)
  85.     for(j=0;j<LENGTH;j++) {
  86.       Level->site[i][j].locchar = FLOOR;
  87.       Level->site[i][j].roomnumber = RS_COUNTRYSIDE;
  88.       Level->site[i][j].showchar = FLOOR;
  89.       Level->site[i][j].lstatus = SEEN+LIT;
  90.       if ((i == 0) || (j == 0) || (i == WIDTH-1) || (j == LENGTH-1))
  91.     Level->site[i][j].p_locf = L_TACTICAL_EXIT;
  92.       else Level->site[i][j].p_locf = L_NO_OP;
  93.     }
  94. }
  95.  
  96. void make_road()
  97. {
  98.   int i,x,y;
  99.   make_plains();
  100.   for(i=0;i<191;i++) {
  101.     do {
  102.       x = random_range(WIDTH);
  103.     } while ((x < WIDTH/2+3) && (x > WIDTH/2-3));
  104.     y = random_range(LENGTH);
  105.     Level->site[x][y].locchar = HEDGE;
  106.     Level->site[x][y].showchar = HEDGE;
  107.     Level->site[x][y].p_locf = L_HEDGE;
  108.   }    
  109.   for(i=0;i<31;i++) {
  110.     do {
  111.       x = random_range(WIDTH);
  112.     } while ((x < WIDTH/2+3) && (x > WIDTH/2-3));
  113.     y = random_range(LENGTH);
  114.     Level->site[x][y].locchar = WATER;
  115.     Level->site[x][y].showchar = WATER;
  116.     Level->site[x][y].p_locf = L_WATER;
  117.   }    
  118.   for(i=0;i<127;i++) {
  119.     do {
  120.       x = random_range(WIDTH);
  121.     } while ((x < WIDTH/2+3) && (x > WIDTH/2-3));
  122.     y = random_range(LENGTH);
  123.     Level->site[x][y].locchar = RUBBLE;
  124.     Level->site[x][y].showchar = RUBBLE;
  125.     Level->site[x][y].p_locf = L_RUBBLE;
  126.   }    
  127. }
  128.  
  129.  
  130.  
  131. void make_forest()
  132. {
  133.   int i,x,y,x1,y1;
  134.   make_plains();
  135.   for(i=0;i<255;i++){
  136.     x = random_range(WIDTH);
  137.     y = random_range(LENGTH);
  138.     Level->site[x][y].locchar = HEDGE;
  139.     Level->site[x][y].showchar = HEDGE;
  140.     Level->site[x][y].p_locf = L_HEDGE;
  141.   }
  142.   x = 0; 
  143.   x1 = WIDTH;
  144.   y = random_range(LENGTH);
  145.   y1 = random_range(LENGTH);
  146.   straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  147. }
  148.  
  149.  
  150. void make_jungle()
  151. {
  152.   int i,x,y;
  153.   make_plains();
  154.   for(i=0;i<511;i++){
  155.     x = random_range(WIDTH);
  156.     y = random_range(LENGTH);
  157.     Level->site[x][y].locchar = HEDGE;
  158.     Level->site[x][y].showchar = HEDGE;
  159.     Level->site[x][y].p_locf = L_HEDGE;
  160.   }
  161. }
  162.  
  163.  
  164. void make_river()
  165. {
  166.   int i,x,y,x1,y1;
  167.   make_plains();
  168.   for(i=0;i<127;i++){
  169.     x = random_range(WIDTH);
  170.     y = random_range(LENGTH);
  171.     Level->site[x][y].locchar = HEDGE;
  172.     Level->site[x][y].showchar = HEDGE;
  173.     Level->site[x][y].p_locf = L_HEDGE;
  174.   }
  175.   x = 0; 
  176.   x1 = WIDTH;
  177.   y = random_range(LENGTH);
  178.   y1 = random_range(LENGTH);
  179.   straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  180.   for(i=0;i<7;i++) {
  181.     if (y > LENGTH/2) y--;
  182.     else y++;
  183.     if (y1 > LENGTH/2) y1--;
  184.     else y1++;
  185.     straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  186.   }
  187. }
  188.  
  189.  
  190. void make_mountains()
  191. {
  192.   int i,x,y,x1,y1;
  193.   make_plains();
  194.   for(i=0;i<256;i++){
  195.     x = random_range(WIDTH);
  196.     y = random_range(LENGTH);
  197.     Level->site[x][y].locchar = RUBBLE;
  198.     Level->site[x][y].showchar = RUBBLE;
  199.     Level->site[x][y].p_locf = L_RUBBLE;
  200.   }
  201.   x = 0; 
  202.   x1 = WIDTH;
  203.   y = random_range(LENGTH);
  204.   y1 = random_range(LENGTH);
  205.   straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  206.   for(i=0;i<7;i++) {
  207.     x = random_range(WIDTH); 
  208.     x1 = random_range(WIDTH);
  209.     y = 0;
  210.     y1 = LENGTH;
  211.     straggle_corridor(x,y,x1,y1,WATER,RS_COUNTRYSIDE);
  212.   }
  213. }
  214.  
  215.  
  216.  
  217. void make_swamp()
  218. {
  219.   int i,x,y;
  220.   make_plains();
  221.   for(i=0;i<511;i++){
  222.     x = random_range(WIDTH);
  223.     y = random_range(LENGTH);
  224.     Level->site[x][y].locchar = WATER;
  225.     Level->site[x][y].showchar = WATER;
  226.     Level->site[x][y].p_locf = L_WATER;
  227.   }
  228.  
  229.   for(i=0;i<255;i++){
  230.     x = random_range(WIDTH);
  231.     y = random_range(LENGTH);
  232.     Level->site[x][y].locchar = HEDGE;
  233.     Level->site[x][y].showchar = HEDGE;
  234.     Level->site[x][y].p_locf = L_HEDGE;
  235.   }
  236. }
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. /* builds a room. Then, for each successive room, sends off at least one
  244. corridor which is guaranteed to connect up to another room, thus guaranteeing
  245. fully connected level. */
  246.  
  247. void room_level()
  248. {
  249.   int i,fx,fy,tx,ty,t,l,e;
  250.   char rsi;
  251.  
  252.   Level->numrooms = random_range(8)+9;
  253.  
  254.   do {
  255.     t = random_range(LENGTH-10)+1;
  256.     l = random_range(WIDTH-10)+1;
  257.     e = 4+random_range(5);
  258.   } while ((Level->site[l][t].roomnumber != RS_WALLSPACE) ||
  259.        (Level->site[l+e][t].roomnumber != RS_WALLSPACE) ||
  260.        (Level->site[l][t+e].roomnumber != RS_WALLSPACE) ||
  261.        (Level->site[l+e][t+e].roomnumber != RS_WALLSPACE));
  262.   if (Current_Dungeon == E_SEWERS) {
  263.     if (random_range(2)) rsi = ROOMBASE+25;
  264.     else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  265.   }
  266.   else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  267.   build_room(l,t,e,rsi,1);
  268.  
  269.  
  270.   for (i=2;i<=Level->numrooms;i++) {
  271.     do {
  272.       t = random_range(LENGTH-10)+1;
  273.       l = random_range(WIDTH-10)+1;
  274.       e = 4+random_range(5);
  275.     } while ((Level->site[l][t].roomnumber != RS_WALLSPACE) ||
  276.          (Level->site[l+e][t].roomnumber != RS_WALLSPACE) ||
  277.          (Level->site[l][t+e].roomnumber != RS_WALLSPACE) ||
  278.          (Level->site[l+e][t+e].roomnumber != RS_WALLSPACE));
  279.     if (Current_Dungeon == E_SEWERS) {
  280.       if (random_range(2)) rsi = ROOMBASE+25;
  281.       else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  282.     }
  283.     else rsi = ROOMBASE+random_range(NUMROOMNAMES);
  284.     build_room(l,t,e,rsi,i);
  285.     
  286.  
  287.     /* corridor which is guaranteed to connect */
  288.     findspace(&tx,&ty,i);
  289.  
  290.     /* figure out where to start corridor from */
  291.     if ((ty <= t) && (tx <= l+e)) {
  292.       fx = l+1+random_range(e-1);
  293.       fy = t;
  294.     }
  295.     else if ((tx >= l+e) && (ty <= t+e)) {
  296.       fx = l+e;
  297.       fy = t+1+random_range(e-1);
  298.     }
  299.     else if ((ty >= t+e) && (tx >= l)) {
  300.       fx = l+1+random_range(e-1);
  301.       fy = t+e;
  302.     }
  303.     else {
  304.       fx = l;
  305.       fy = t+1+random_range(e-1);
  306.     }
  307.  
  308.     room_corridor(fx,fy,tx,ty,i);
  309.  
  310.  
  311.     /* corridor which may not go anywhere */
  312.     if (random_range(2)) {
  313.       findspace(&tx,&ty,i);
  314.       if ((ty <= t) && (tx <= l+e)) {
  315.     fx = l+1+random_range(e-1);
  316.     fy = t;
  317.       }
  318.       else if ((tx >= l+e) && (ty <= t+e)) {
  319.     fx = l+e;
  320.     fy = t+1+random_range(e-1);
  321.       }
  322.       else if ((ty >= t+e) && (tx >= l)) {
  323.     fx = l+1+random_range(e-1);
  324.     fy = t+e;
  325.       }
  326.       else {
  327.     fx = l;
  328.     fy = t+1+random_range(e-1);
  329.       }
  330.       room_corridor(fx,fy,tx,ty,i);
  331.     }
  332.   }
  333.  
  334.   if (Current_Dungeon == E_SEWERS) {
  335.     if (Level->depth == SEWERLEVELS) {
  336.       findspace(&tx,&ty,-1);
  337.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  338.       Level->mlist->next = NULL;
  339.       Level->mlist->m = 
  340.     Level->site[tx][ty].creature = 
  341.       ((pmt) make_creature(ML7+5)); /* The Great Wyrm */
  342.       Level->mlist->m->x = tx;
  343.       Level->mlist->m->y = ty;
  344.     }
  345.   }
  346.   else if (Current_Environment == E_CASTLE) {
  347.     if (Level->depth == CASTLELEVELS) {
  348.       findspace(&tx,&ty,-1);
  349.       Level->site[tx][ty].locchar = DOWN;
  350.       Level->site[tx][ty].p_locf = L_ENTER_COURT;
  351.     }
  352.   }
  353.   else if (Current_Environment == E_VOLCANO) {
  354.     if (Level->depth == VOLCANOLEVELS) {
  355.       findspace(&tx,&ty,-1);
  356.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  357.       Level->mlist->next = NULL;
  358.       Level->mlist->m = 
  359.     Level->site[tx][ty].creature = 
  360.       ((pmt) make_creature(ML10+4)); /* The dark emp */
  361.       Level->mlist->m->x = tx;
  362.       Level->mlist->m->y = ty;
  363.     }
  364.   }
  365.   populate_level(Current_Environment);
  366.   stock_level();
  367. }
  368.  
  369.  
  370.  
  371. /* goes from f to t unless it hits a site which is not a wall and doesn't
  372.    have buildaux field == baux */
  373. void room_corridor(fx,fy,tx,ty,baux)
  374. int fx,fy,tx,ty,baux;
  375. {
  376.   int dx,dy,continuing = TRUE;
  377.  
  378.   dx = sign(tx-fx);
  379.   dy = sign(ty-fy);
  380.  
  381.   makedoor(fx,fy);
  382.  
  383.   fx+=dx;
  384.   fy+=dy;
  385.  
  386.   while(continuing) {
  387.     Level->site[fx][fy].locchar = FLOOR;
  388.     Level->site[fx][fy].roomnumber = RS_CORRIDOR;
  389.     Level->site[fx][fy].buildaux = baux;
  390.     dx = sign(tx-fx);
  391.     dy = sign(ty-fy);
  392.     if ((dx != 0) && (dy != 0)) {
  393.       if (random_range(2)) dx = 0;
  394.       else if (random_range(2)) dy = 0;
  395.     }
  396.     fx+=dx;
  397.     fy+=dy;
  398.     continuing = (((fx != tx) || (fy != ty)) &&
  399.           ((Level->site[fx][fy].buildaux == 0) ||
  400.            (Level->site[fx][fy].buildaux == baux)));
  401.   }
  402.   makedoor(fx,fy);
  403. }
  404.  
  405.  
  406.  
  407.  
  408.  
  409. void maze_level()
  410. {
  411.   int i,j,tx,ty,mid;
  412.   char rsi;
  413.   if (Current_Environment == E_ASTRAL)
  414.     switch(Level->depth){
  415.     case 1: rsi = RS_EARTHPLANE; break;
  416.     case 2: rsi = RS_AIRPLANE; break;
  417.     case 3: rsi = RS_WATERPLANE; break;
  418.     case 4: rsi = RS_FIREPLANE; break;
  419.     case 5: rsi = RS_HIGHASTRAL; break;
  420.     }
  421.   else rsi = RS_VOLCANO;
  422.   maze_corridor(random_range(WIDTH-1)+1,
  423.         random_range(LENGTH-1)+1,
  424.         random_range(WIDTH-1)+1,
  425.         random_range(LENGTH-1)+1,
  426.         rsi,0);
  427.   if (Current_Dungeon == E_ASTRAL) {
  428.     for(i=0;i<WIDTH;i++) 
  429.       for(j=0;j<LENGTH;j++) 
  430.     if (Level->site[i][j].locchar == WALL)
  431.       switch(Level->depth){
  432.       case 1: Level->site[i][j].aux = 500; break;
  433.       case 2: 
  434.         Level->site[i][j].locchar = WHIRLWIND;
  435.         Level->site[i][j].p_locf = L_WHIRLWIND;
  436.         break;
  437.       case 3: 
  438.         Level->site[i][j].locchar = WATER;
  439.         Level->site[i][j].p_locf = L_WATER;
  440.         break;
  441.       case 4:
  442.         Level->site[i][j].locchar = FIRE;
  443.         Level->site[i][j].p_locf = L_FIRE;
  444.         break;
  445.       case 5: 
  446.         Level->site[i][j].locchar = ABYSS;
  447.         Level->site[i][j].p_locf = L_ABYSS;
  448.         break;
  449.       }
  450.     switch(Level->depth) {
  451.     case 1: mid = ML10+5; break; /* Elemental Lord of Earth */
  452.     case 2: mid = ML10+6; break; /* Elemental Lord of Air */
  453.     case 3: mid = ML10+7; break; /* Elemental Lord of Water */
  454.     case 4: mid = ML10+8; break; /* Elemental Lord of Fire */
  455.     case 5: mid = ML10+9; break; /* Elemental Master */
  456.     }
  457.     if (Level->depth == 5) {
  458.       findspace(&tx,&ty,-1);
  459.       Level->site[tx][ty].p_locf = L_ENTER_CIRCLE;
  460.       Level->site[tx][ty].locchar = DOWN;
  461.     }
  462.     if (! gamestatusp(COMPLETED_ASTRAL)) {
  463.       findspace(&tx,&ty,-1);
  464.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  465.       Level->mlist->next = NULL;
  466.       Level->mlist->m = 
  467.     Level->site[tx][ty].creature = 
  468.       ((pmt) make_creature(mid)); 
  469.       Level->mlist->m->x = tx;
  470.       Level->mlist->m->y = ty;
  471.     }
  472.   }
  473.   else if (Current_Environment == E_VOLCANO) {
  474.     if (Level->depth == VOLCANOLEVELS) {
  475.       findspace(&tx,&ty,-1);
  476.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  477.       Level->mlist->next = NULL;
  478.       Level->mlist->m = 
  479.     Level->site[tx][ty].creature = 
  480.       ((pmt) make_creature(ML10+4)); /* The dark emp */
  481.       Level->mlist->m->x = tx;
  482.       Level->mlist->m->y = ty;
  483.     }
  484.   }
  485.   populate_level(Current_Environment);
  486.   stock_level();
  487. }
  488.  
  489.  
  490. /* keep drawing corridors recursively for 2^5 endpoints */
  491. void maze_corridor(fx,fy,tx,ty,rsi,num)
  492. int fx,fy,tx,ty;
  493. char rsi,num;
  494. {
  495.   if (num < 6) {
  496.     straggle_corridor(fx,fy,tx,ty,FLOOR,rsi);
  497.     maze_corridor(tx,ty,
  498.           random_range(WIDTH-1)+1,
  499.           random_range(LENGTH-1)+1,
  500.           rsi,num+1);
  501.     
  502.   }
  503. }
  504.  
  505.  
  506.  
  507.  
  508.  
  509.